import 'package:ideology/shared/widgets/code_input/core/text_buffer.dart';

/// 编辑器控制器，集中管理光标位置、选区以及所有文本编辑操作
class EditorController {
  final TextBuffer buffer; // 文本缓冲区（必须外部传入）
  int cursorPosition; // 光标在文本中的绝对位置

  int? _preferredColumn; // 期望列，用于上下移动保持列位置

  // —— 选区相关 ——————————————————————————
  int? _selectionAnchor; // 选区锚点（按住 Shift 时第一次光标位置）
  bool get hasSelection =>
      _selectionAnchor != null && _selectionAnchor != cursorPosition;

  /// 选区开始位置（保证 <= end）
  int get selectionStart => !hasSelection
      ? cursorPosition
      : (_selectionAnchor! < cursorPosition
            ? _selectionAnchor!
            : cursorPosition);

  /// 选区结束位置（保证 >= start）
  int get selectionEnd => !hasSelection
      ? cursorPosition
      : (_selectionAnchor! < cursorPosition
            ? cursorPosition
            : _selectionAnchor!);

  /// 开始扩展选区（在处理 Shift+方向键时调用）
  void startSelection() {
    _selectionAnchor ??= cursorPosition;
  }

  /// 清除选区（在普通光标移动或点击时调用）
  void clearSelection() {
    _selectionAnchor = null;
  }

  /// 外部直接设置选区（供 EditableText 同步使用）
  void setSelection(int start, int end) {
    _selectionAnchor = start;
    cursorPosition = end;
  }

  /// 辅助：如有选区，先删除选中文本
  void _deleteSelectionIfAny() {
    if (hasSelection) {
      buffer.delete(selectionStart, selectionEnd);
      cursorPosition = selectionStart;
      clearSelection();
    }
  }

  /// 构造函数，支持自定义光标初始位置（默认缓冲区末尾）
  EditorController({required this.buffer, int? initPosition})
    : cursorPosition = initPosition ?? buffer.length,
      _preferredColumn = null;

  // ======== 文本编辑操作 ========

  /// 插入普通文本（可包含多字符）
  void insertText(String text) {
    _deleteSelectionIfAny();
    buffer.insert(cursorPosition, text);
    cursorPosition += text.length;
    _preferredColumn = null;
  }

  /// 退格（删除光标前一个字符）
  void backspace() {
    if (hasSelection) {
      _deleteSelectionIfAny();
    } else if (cursorPosition > 0) {
      buffer.delete(cursorPosition - 1, cursorPosition);
      cursorPosition--;
      _preferredColumn = null;
    }
  }

  /// 删除光标后的一个字符（Delete 键，不移动光标）
  void delete() {
    if (hasSelection) {
      _deleteSelectionIfAny();
    } else if (cursorPosition < buffer.getText().length) {
      buffer.delete(cursorPosition, cursorPosition + 1);
      _preferredColumn = null;
    }
  }

  /// 插入换行符（等价于按下回车 Enter）
  void enter() => insertText('\n');

  // ======== 光标移动（不带选区） ========
  void moveLeft() {
    if (cursorPosition > 0) cursorPosition--;
    _preferredColumn = null;
  }

  void moveRight() {
    if (cursorPosition < buffer.length) cursorPosition++;
    _preferredColumn = null;
  }

  void moveLineStart() {
    _moveToLineBoundary(start: true);
  }

  void moveLineEnd() {
    _moveToLineBoundary(start: false);
  }

  void moveUp() {
    _moveVertically(up: true);
  }

  void moveDown() {
    _moveVertically(up: false);
  }

  // —— 私有助手 ——————————————————————————————————
  void _moveToLineBoundary({required bool start}) {
    final lines = buffer.getLines();
    int pos = 0, row = 0;
    for (; row < lines.length; row++) {
      if (cursorPosition <= pos + lines[row].length) break;
      pos += lines[row].length + 1;
    }
    cursorPosition = start ? pos : pos + lines[row].length;
    _preferredColumn = null;
  }

  void _moveVertically({required bool up}) {
    final lines = buffer.getLines();
    int pos = cursorPosition, row = 0, col = pos;
    for (; row < lines.length; row++) {
      if (col <= lines[row].length) break;
      col -= lines[row].length + 1;
    }
    _preferredColumn ??= col;
    if (up && row > 0) {
      final prevLen = lines[row - 1].length;
      int newPos = 0;
      for (int i = 0; i < row - 1; i++) {
        newPos += lines[i].length + 1;
      }
      cursorPosition = newPos + _preferredColumn!.clamp(0, prevLen);
    } else if (!up && row < lines.length - 1) {
      final nextLen = lines[row + 1].length;
      int newPos = 0;
      for (int i = 0; i < row + 1; i++) {
        newPos += lines[i].length + 1;
      }
      cursorPosition = newPos + _preferredColumn!.clamp(0, nextLen);
    }
  }
}
